/*
	Copyright 2007-2010 Petr Ohlidal

	This file is a part of GrobMaker

	GrobMaker is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	GrobMaker is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with GrobMaker.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "LuaGrobfileWriter.hpp"
#include <iomanip>
#include "Exception.hpp"
#include "OutputData.hpp"
#include "InputData.hpp"
#include "Util/Vector.hpp"

namespace GrobMaker{

LuaGrobfileWriter::LuaGrobfileWriter
	(std::string grobfilePath, OutputData& outputData, InputData& inputData):
		outData(outputData),inData(inputData){
	//this->outData = outputData;
	//this->inData = inData;
	this->grobfile.open(grobfilePath.c_str());
	if(!this->grobfile.is_open()){
		std::stringstream err;
		err<<"Failed to open grobfile '"<<grobfilePath<<"' for writing";
		throw Exception(err);
	}
	this->singlePivot = this->outData.pivots.size()==1;
}

void LuaGrobfileWriter::printSprites(){
	this->grobfile<<"local spritesDir='"<<this->outData.spritesOutDir<<"'"<<std::endl;
	// Single sprite
	if(this->inData.singleSprite){
		float x = this->outData.imageAreas.front().x-this->outData.pivots.front().x;
		float y = this->outData.imageAreas.front().y-this->outData.pivots.front().y;
		this->grobfile<<"SingleSprite={x="<<x<<",y="<<y
			<<",path=spritesDir..'Sprite.png'}"<<std::endl;
	}
	else{
		this->grobfile<<"Sprites={"<<std::endl;
		std::list<Vector>::iterator pivotIt = this->outData.pivots.begin();
		std::list<Rectangle>::iterator trimIt = this->outData.imageAreas.begin();
		for(int i=0; i<this->inData.noAngles; i++){
			Rectangle& trimRect = *trimIt;
			Vector& pivotVec = *pivotIt;
			this->grobfile<<"\t{x="<<trimRect.x-pivotVec.x
				<<",y="<<trimRect.y-pivotVec.y
				<<",path=spritesDir..'"<<std::setfill('0')<<std::setw(3)<<i<<'.'<<this->inData.imgOutputExtension<<"'}"
				<<((i<(this->inData.noAngles-1))?",\n":"\n");
			if(!this->singlePivot){
				pivotIt++;
			}
			trimIt++;
		}
		this->grobfile<<"}"<<std::endl;
	}
}

void LuaGrobfileWriter::printShades(){
	if(this->outData.shades.size()>0){
		if(this->outData.shades.size()==1){
			// Single shade
			Area& shade = this->outData.shades.front();
			Vector& pivot = this->outData.pivots.front();
			this->grobfile<<"SingleShade={x="
				<<shade.x-pivot.x<<",y="<<shade.y-pivot.y
					<<",w="<<shade.w<<",h="<<shade.h<<"}"<<std::endl;
		}
		else{
			this->grobfile<<"Shades={"<<std::endl;
			std::list<Vector>::iterator pivotIt = this->outData.pivots.begin();
			std::list<Area>::iterator shadeIt = this->outData.shades.begin();
			for(int i=0; i<this->inData.noAngles; i++){
				this->grobfile<<"\t{x="<<shadeIt->x-pivotIt->x<<",y="<<shadeIt->y-pivotIt->y
					<<",w="<<shadeIt->w<<",h="<<shadeIt->h<<"}"
					<<(i<(this->inData.noAngles-1)?",\n":"\n");
				if(!this->singlePivot){
					pivotIt++;
				}
				shadeIt++;
			}
			this->grobfile<<"}"<<std::endl;
		}
	}
}

void LuaGrobfileWriter::printImageAreas(){
	if(this->outData.imageAreas.size()==1){
		Rectangle imageArea = this->outData.imageAreas.front();
		Vector pivot = this->outData.pivots.front();
		this->grobfile<<"SingleImageArea={x1="<<imageArea.x-pivot.x
			<<",y1="<<imageArea.y-pivot.y
			<<",x2="<<(imageArea.x+imageArea.w)-pivot.x
			<<",y2="<<(imageArea.y+imageArea.h)-pivot.y<<"}"<<std::endl;
	}
	else{
		this->grobfile<<"ImageAreas={"<<std::endl;
		std::list<Vector>::iterator pivotIt = this->outData.pivots.begin();
		std::list<Rectangle>::iterator imaIt = this->outData.imageAreas.begin();
		for(int i=0; i<this->inData.noAngles; i++){
			this->grobfile<<"\t{x1="<<imaIt->x-pivotIt->x
				<<",y1="<<imaIt->y-pivotIt->y
				<<",x2="<<(imaIt->x+imaIt->w)-pivotIt->x
				<<",y2="<<(imaIt->y+imaIt->h)-pivotIt->y<<"}"
				<<((i+1<this->inData.noAngles)?",\n":"\n");
			if(!this->singlePivot){
				pivotIt++;
			}
			imaIt++;
		}
		this->grobfile<<"}"<<std::endl;
	}
}

void LuaGrobfileWriter::printPegs(){
	if(this->outData.pegs.size()==0){
		return;
	}
	this->grobfile<<"Pegs={"<<std::endl;
	int noPegs = outData.pegs.size();
	int pegIndex = 0;
	for(std::list< Peg >::iterator pegIt=this->outData.pegs.begin();
		pegIt!=this->outData.pegs.end();
		pegIt++){
		if(pegIt->positions.size()==1){ // Single peg
			PegPosition pegPos = pegIt->positions.front();
			Vector pivot = this->outData.pivots.front();
			this->grobfile<<"\t{\n\t\tname=\""<<pegIt->name<<",\\n\t\tposition={x="
				<<pegPos.x-pivot.x<<",y="<<pegPos.y-pivot.y<<",h="<<pegPos.h<<"}"<<std::endl;
		}
		else{ // Peg per angle
			this->grobfile<<"\t{\n\t\tname=\""<<pegIt->name<<"\",\n\t\tpositions={"<<std::endl;
			std::list<Vector>::iterator pivotIt = this->outData.pivots.begin();
			std::list<PegPosition>::iterator pegPosIt = pegIt->positions.begin();
			for(int i=0; i<this->inData.noAngles; i++){
				this->grobfile<<"\t\t\t{x="<<pegPosIt->x-pivotIt->x<<",y="<<pegPosIt->y-pivotIt->y
					<<",h="<<pegPosIt->h<<"}"
					<<((i+1<this->inData.noAngles)?",\n":"\n");
				if(!this->singlePivot){
					pivotIt++;
				}
				pegPosIt++;
			}
			// End of peg table. Unless it's the last peg, put a comma after the table literal.
			this->grobfile<<"\t\t}\n\t}"<<( (pegIndex==noPegs-1) ? "" : "," )<<'\n';
		}
		pegIndex++;
	}
	this->grobfile<<"}"<<std::endl;
}

LuaGrobfileWriter::~LuaGrobfileWriter(){
	this->grobfile.close();
}

void LuaGrobfileWriter::printHeader(){
	this->grobfile
		<<"Name='"<<this->inData.grobName
		<<"'\nNoVisualAngles="<<this->inData.noAngles<<std::endl;
}

} // namespace GrobMaker
